package session

import (
	web "geektime-go-homework/web/class2"
	"github.com/google/uuid"
	"net/http"
)

type Manager struct {
	Propagator
	Store
	CtxSessionKey string
}

func NewManager(propagator Propagator) *Manager {
	return &Manager{Propagator: propagator}
}

func (m *Manager) GetSession(ctx *web.Context) (Session, error) {
	if ctx.UserValues == nil {
		ctx.UserValues = make(map[string]any, 10)
	}
	val, ok := ctx.UserValues[m.CtxSessionKey]
	if ok {
		return val.(Session), nil
	}
	sessionId, err := m.Propagator.Extra(ctx.Req)
	if err != nil {
		ctx.RespData = []byte("登录过期")
		ctx.RespStatusCode = http.StatusUnauthorized
		return nil, err
	}
	session, err := m.Get(ctx.Req.Context(), sessionId)
	if err != nil {
		return nil, err
	}
	ctx.UserValues[m.CtxSessionKey] = session
	return session, err
}

func (m *Manager) InitSession(ctx *web.Context) (Session, error) {
	sessionId := uuid.New().String()
	session, err := m.Generate(ctx.Req.Context(), sessionId)
	if err != nil {
		ctx.RespData = []byte("session 初始化失败")
		ctx.RespStatusCode = http.StatusInternalServerError
		return nil, err
	}
	err = m.Inject(sessionId, ctx.Resp)
	if err != nil {
		ctx.RespData = []byte("注入session失败")
		ctx.RespStatusCode = http.StatusInternalServerError
		return nil, err
	}

	return session, nil
}

func (m *Manager) RemoveSession(ctx *web.Context) error {
	session, err := m.GetSession(ctx)
	if err != nil {
		return err
	}

	err = m.Store.Remove(ctx.Req.Context(), session.ID())
	if err != nil {
		return err
	}

	return m.Propagator.Remove(ctx.Resp)
}

func (m *Manager) RefreshSession(ctx *web.Context) error {
	session, err := m.GetSession(ctx)
	if err != nil {
		return err
	}
	return m.Refresh(ctx.Req.Context(), session.ID())
}
